///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#ifndef __CompositionTechnique_H__
#define __CompositionTechnique_H__

#include "OgrePrerequisites.h"
#include "OgrePixelFormat.h"
#include "OgreIteratorWrappers.h"

namespace Ogre {
	
	
	
	class _OgreExport CompositionTechnique : public MemAlloc_Resource
    {
    public:
        CompositionTechnique(Compositor *parent);
        virtual ~CompositionTechnique();
    
        //The scope of a texture defined by the compositor
        enum TextureScope { 
            //Local texture - only available to the compositor passes in this technique
            TS_LOCAL, 
            //Chain texture - available to the other compositors in the chain
            TS_CHAIN, 
            //Global texture - available to everyone in every scope
            TS_GLOBAL 
        };

        /// Local texture definition
        class TextureDefinition : public MemAlloc_Resource
        {
        public:
            String name;
			//Texture definition being a reference is determined by these two fields not being empty.
			String refCompName; //If a reference, the name of the compositor being referenced
			String refTexName;	//If a reference, the name of the texture in the compositor being referenced
            size_t width;       // 0 means adapt to target width
            size_t height;      // 0 means adapt to target height
			float widthFactor;  // multiple of target width to use (if width = 0)
			float heightFactor; // multiple of target height to use (if height = 0)
            PixelFormatList formatList; // more than one means MRT
			bool fsaa;			// FSAA enabled; true = determine from main target (if render_scene), false = disable
			bool hwGammaWrite;	// Do sRGB gamma correction on write (only 8-bit per channel formats) 
			uint16 depthBufferId;//Depth Buffer's pool ID. (unrelated to "pool" variable below)
			bool pooled;		// whether to use pooled textures for this one
            TextureScope scope; // Which scope has access to this texture

			TextureDefinition() :width(0), height(0), widthFactor(1.0f), heightFactor(1.0f), 
				fsaa(true), hwGammaWrite(false), depthBufferId(1), pooled(false), scope(TS_LOCAL) {}
        };
        /// Typedefs for several iterators
        typedef vector<CompositionTargetPass *>::type TargetPasses;
        typedef VectorIterator<TargetPasses> TargetPassIterator;
        typedef vector<TextureDefinition*>::type TextureDefinitions;
        typedef VectorIterator<TextureDefinitions> TextureDefinitionIterator;
        
        
        TextureDefinition *createTextureDefinition(const String &name);
        
        
        void removeTextureDefinition(size_t idx);
        
        
        TextureDefinition *getTextureDefinition(size_t idx);
        
		
		TextureDefinition *getTextureDefinition(const String& name);

		
        size_t getNumTextureDefinitions();
        
        
        void removeAllTextureDefinitions();
        
        
        TextureDefinitionIterator getTextureDefinitionIterator(void);
        
        
        CompositionTargetPass *createTargetPass();
        
        
        void removeTargetPass(size_t idx);
        
        
        CompositionTargetPass *getTargetPass(size_t idx);
        
        
        size_t getNumTargetPasses();
        
        
        void removeAllTargetPasses();
        
        
        TargetPassIterator getTargetPassIterator(void);
        
        
        CompositionTargetPass *getOutputTargetPass();
        
        
        virtual bool isSupported(bool allowTextureDegradation);
        
		
		virtual void setSchemeName(const String& schemeName);
		
		const String& getSchemeName() const { return mSchemeName; }
        
		
		void setCompositorLogicName(const String& compositorLogicName) 
			{ mCompositorLogicName = compositorLogicName; }
		
		const String& getCompositorLogicName() const { return mCompositorLogicName; }

        
        Compositor *getParent();
    private:
        /// Parent compositor
        Compositor *mParent;
        /// Local texture definitions
        TextureDefinitions mTextureDefinitions;
        
        /// Intermediate target passes
        TargetPasses mTargetPasses;
        /// Output target pass (can be only one)
        CompositionTargetPass *mOutputTarget;  

		/// Optional scheme name
		String mSchemeName;
		
		/// Optional compositor logic name
		String mCompositorLogicName;

    };
	
	

}

#endif
